Skip to content

Use trusted publishing for PyPI releases - #193

Merged
mraineri merged 2 commits into
DMTF:mainfrom
jyundt:feat/trusted-pypi-publishing
Aug 25, 2026
Merged

Use trusted publishing for PyPI releases#193
mraineri merged 2 commits into
DMTF:mainfrom
jyundt:feat/trusted-pypi-publishing

Conversation

@jyundt

@jyundt jyundt commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Summary

  • preserve the existing push-button process for updating versions and changelogs and creating a tagged GitHub release
  • move release preparation into a separate manually dispatched workflow
  • dispatch the PyPI publishing workflow at the newly created release tag
  • verify that the tag matches setup.py, redfish.__version__ and CHANGELOG.md
  • separate the unprivileged build job from the PyPI publishing job
  • require explicit approval through the protected pypi GitHub environment
  • replace the long-lived PyPI API token with OIDC Trusted Publishing
  • publish PyPI attestations and pin all third-party actions to immutable commits
  • document the revised maintainer release process

Motivation

The current release workflow updates the version and changelog, pushes those changes, creates the GitHub release, builds the package and publishes it with a stored PYPI_API_TOKEN. Although the workflow is public, packages published this way do not include PyPI provenance attestations.

This change keeps the existing push-button release preparation. The manually dispatched workflow still accepts the version and changelog entries, updates the release metadata, pushes the changes to main and creates the tagged GitHub release.

PyPI publication is handled separately. After creating the release, the preparation workflow dispatches main.yml at the new tag. The publishing workflow verifies that it is running from a published release tag, checks the package and changelog versions, builds the distributions without publishing credentials and transfers only those distributions to the publishing job.

The publishing job waits for approval through the protected pypi GitHub environment. Once approved, it authenticates to PyPI using a short-lived OIDC credential and uploads provenance attestations with the distributions.

This was prompted by the dependency-transparency review for the downstream Home Assistant Redfish integration.

Closes #194.

Maintainer setup required

Before the first release using this workflow:

  1. Create a pypi environment in this GitHub repository and configure at least one required reviewer.
  2. On the PyPI redfish project, confirm that the GitHub Trusted Publisher is configured with:
    • owner: DMTF
    • repository: python-redfish-library
    • workflow: main.yml
    • environment: pypi
  3. After the first trusted publication succeeds, remove the unused PYPI_API_TOKEN repository secret.

This draft should not be marked ready until the protected GitHub environment and PyPI Trusted Publisher have both been confirmed.

Validation

  • actionlint with ShellCheck for both workflows: passed
  • pedantic zizmor audit for both workflows: no findings
  • release metadata update simulation: passed
  • invalid versions, multiline changelog entries and duplicate versions: rejected as expected
  • mixed line endings in the existing version files: preserved
  • source distribution and wheel build: passed
  • twine check for both distributions: passed
  • Python 3.14 tests: 63 tests and 35 subtests passed
  • DCO: passed

No GitHub release or PyPI publication was triggered during validation.

The existing tox -e pep8 target continues to report pre-existing formatting errors in files untouched by this change.

Signed-off-by: Jacob Yundt <me@jyundt.com>
Comment thread README.rst Outdated
Comment on lines +319 to +322
1. Update ``CHANGELOG.md``, ``setup.py``, and ``src/redfish/__init__.py`` with
the new version in a pull request.
2. Merge the pull request.
3. Create a GitHub release from the merged commit with the version as its tag.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we keep this its own workflow (thus preserving the removed portions in the Release and Publish flow). I like the ease of having a push-button approach to updating versions/changelogs.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implemented in ad19d8c. The new prepare-release.yml workflow preserves the existing version, changelog and tagged-release automation. It then dispatches main.yml at the new tag.

The publishing workflow verifies the published release and version metadata, builds without publishing credentials and waits for approval on the pypi environment before publishing through OIDC.

The remaining setup step is to configure the repository’s pypi environment with a required reviewer.

@PeterKchen2

Copy link
Copy Markdown
Contributor

@mraineri It seems the current hesitation stems from a reluctance to lose the convenience of the original "push-button" automation for managing versions and changelogs. However, GitHub Actions can actually deliver the best of both worlds—preserving that ease of use while fully complying with PyPI's strict OIDC security requirements.

We can split this into a seamless two-step automated workflow:

  • Step 1: Automated PR Generation (The "Push-Button" Phase)
    The maintainer triggers a workflow via workflow_dispatch (manually). This job automatically calculates the next version number, updates CHANGELOG.md/setup.py, and automatically opens a new Pull Request with those changes.
  • Step 2: Secure OIDC Publishing (The "Trusted" Phase)
    Once the maintainer reviews and merges that PR, creating a GitHub Release will trigger the second, privileged workflow. This job uses the temporary GitHub OIDC token to securely publish to PyPI and upload the required provenance attestations.

By separating the repository automation from the secure publication phase, we can maintain the exact single-button convenience the maintainers prefer, while granting Home Assistant the publicly verifiable supply chain transparency it requires.

What do you think about this approach?
ainers prefer, while granting Home Assistant the publicly verifiable supply chain transparency it requires.

@jyundt

jyundt commented Aug 25, 2026

Copy link
Copy Markdown
Contributor Author

Recap of quick chat with @mraineri

I’ll split this into two workflows:

  1. A manually dispatched workflow that preserves the current version/changelog update and tagged-release automation.
  2. The trusted-publishing workflow which builds from that release tag and publishes through OIDC.

I’ll put the PyPI publishing job behind approval on the pypi GitHub environment. Creating the release will prepare the tagged build but a maintainer will still need to explicitly approve the PyPI publication.

Signed-off-by: Jacob Yundt <me@jyundt.com>
@jyundt
jyundt marked this pull request as ready for review August 25, 2026 15:55
@mraineri

Copy link
Copy Markdown
Contributor

Approving and merging out of cycle to test out the flow

@mraineri
mraineri merged commit 694dffd into DMTF:main Aug 25, 2026
2 checks passed
@jyundt
jyundt deleted the feat/trusted-pypi-publishing branch August 25, 2026 18:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Switch PyPI releases to trusted publishing

3 participants